﻿/*----------------------------------------------------
 * Author : Tharinduni Udugamasuriya
 * Date : 04th August 2014
 * BaseViewModel : Base View Model Class + MVVM 
 ---------------------------------------------------*/

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Input;
using DSPL.Contracts.Command;
using DSPL.Contracts.Interfaces;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using DSPL.Contracts.Common;


namespace DSPL.Contracts.ViewModel
{
    public class BaseViewModel : INotifyPropertyChanged
    {

        #region Private Memeber field
        private DataRow drCurrent;
        private SqlTransaction sqlTran;
        private DataTable dtFormDataContext;
        private ICommand preDataValidate;
        private ICommand postDataValidate;
        private ICommand postDataUpdate;
        private ICommand postDataDelete;
        private ICommand postDataInsert;
        private ICommand preDataDelete;
        private ICommand preDataUpdate;
        private ICommand preDataInsert;
        private ICommand refreshExternalData;
        private ICommand postDataSaveProcess;
        private ICommand postResetDefault;
        private ICommand preResetDefault;
        private ICommand preDataDelValidation;
        private ICommand windowLoad;
        private ICommand addAdditionalReportParamters;
        private ICommand addAdditionalDataColumns;
        private Modes formMode;
        private DataTable dtChildTransaction;
        private List<IReportParameters> additionalReportParameters;
        private bool _blockBackDatedTransaction;
        private string _reportGroup;
        private string _refGenCode;
        private string _childTableName;
        private string _parentTableName;
        private bool isApprove;

        #endregion

        #region Constructor

        public BaseViewModel()
        {

            ResolveDependancies();
            SetDataSourcesAndProperties();
            EnableDisableSpecificControls();

        }

        #endregion


        public IReadService MasterReadService { get; set; }
        public IWriteService MasterWriteService { get; set; }
        public IColumnWithValue ColumnWithValue { get; set; }
        public ICommonValidations CommonValidations { get; set; }
        public IMessageService MessageService { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;


        public void OnPropertyChanged(string property)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }


        public DataTable DtFormDataContext
        {
            get { return dtFormDataContext; }
            set
            {
                dtFormDataContext = value;
                OnPropertyChanged("DtFormDataContext");
            }
        }

        public DataRow CurrentRow
        {
            get
            {
                return drCurrent;
            }
            set
            {
                drCurrent = value;
                OnPropertyChanged("CurrentRow");
            }
        }


        public SqlTransaction SqlTran
        {
            get { return sqlTran; }
            set
            {
                sqlTran = value;
                OnPropertyChanged("SqlTran");
            }
        }

        private bool isValid;

        public bool IsValid
        {
            get { return isValid; }
            set
            {
                isValid = value;
                OnPropertyChanged("IsValid");
            }
        }

        public string MessageTitle
        {
            get;
            set;
        }

        public Modes FormMode
        {
            get { return formMode; }
            set
            {
                formMode = value;
                OnPropertyChanged("FormMode");
                EnableDisableSpecificControls();
            }
        }

        public List<IReportParameters> AdditionalReportParameters
        {
            get { return additionalReportParameters; }
            set
            {
                additionalReportParameters = value;
                OnPropertyChanged("AdditionalReportParameters");
            }
        }

        public bool IsApprove
        {
            get { return isApprove; }
            set { isApprove = value; }
        }


        public DataTable DtChildTransaction
        {
            get
            {
                return dtChildTransaction;
            }
            set
            {
                dtChildTransaction = value;
                OnPropertyChanged("DtChildTransaction");
            }
        }

        public bool BlockBackDatedTransaction
        {
            get
            {
                return _blockBackDatedTransaction;
            }
            set
            {
                _blockBackDatedTransaction = value;
                OnPropertyChanged("BlockBackDatedTransaction");
            }
        }

        public string ReportGroup
        {
            get
            {
                return _reportGroup;
            }
            set
            {
                _reportGroup = value;
                OnPropertyChanged("ReportGroup");
            }
        }

        public string RefGenCode
        {
            get { return _refGenCode; }
            set
            {
                _refGenCode = value;
                this.OnPropertyChanged("RefGenCode");

            }
        }

        public string ParentTableName
        {
            get { return _parentTableName; }
            set
            {
                _parentTableName = value;
                this.OnPropertyChanged("ParentTableName");

            }
        }

        public string ChildTableName
        {
            get { return _childTableName; }
            set
            {
                _childTableName = value;
                this.OnPropertyChanged("ChildTableName");

            }
        }


        #region define relay commands

        public ICommand PreDataValidate
        {
            get
            {
                if (this.preDataValidate == null)
                    this.preDataValidate = new RelayCommand(PreDataValidateExecuted);

                return this.preDataValidate;
            }
        }

        public ICommand PostDataValidate
        {
            get
            {
                if (this.postDataValidate == null)
                    this.postDataValidate = new RelayCommand(PostDataValidateExecuted);

                return this.postDataValidate;
            }
        }



        public ICommand PostDataUpdate
        {
            get
            {
                if (this.postDataUpdate == null)
                    this.postDataUpdate = new RelayCommand(PostDataUpdateExecuted);

                return this.postDataUpdate;
            }
        }

        public ICommand PostDataInsert
        {
            get
            {
                if (this.postDataInsert == null)
                    this.postDataInsert = new RelayCommand(PostDataInsertExecuted);

                return this.postDataInsert;
            }
        }

        public ICommand PreDataDelete
        {
            get
            {
                if (this.preDataDelete == null)
                {
                    this.preDataDelete = new RelayCommand(PreDataDeleteExecuted);
                }

                return this.preDataDelete;
            }
        }

        public ICommand PostDataDelete
        {
            get
            {
                if (this.postDataDelete == null)
                {
                    this.postDataDelete = new RelayCommand(PostDataDeleteExecuted);
                }

                return this.postDataDelete;
            }
        }

        public ICommand RefreshExternalDataObjects
        {
            get
            {
                if (this.refreshExternalData == null)
                    this.refreshExternalData = new RelayCommand(RefreshExternalDataObjectsExecueted);

                return this.refreshExternalData;
            }
        }

        public ICommand PreDataInsert
        {
            get
            {
                if (this.preDataInsert == null)
                    this.preDataInsert = new RelayCommand(PreDataInsertExecuted);

                return this.preDataInsert;
            }
        }

        public ICommand PreDataUpdate
        {
            get
            {
                if (this.preDataUpdate == null)
                    this.preDataUpdate = new RelayCommand(PreDataUpdateExecuted);

                return this.preDataUpdate;
            }
        }


        public ICommand WindowLoad
        {
            get
            {
                if (this.windowLoad == null)
                {
                    this.windowLoad = new RelayCommand(WindowLoadExcecuted);
                }
                return this.windowLoad;
            }
        }


        public ICommand PostDataSaveProcess
        {
            get
            {
                if (this.postDataSaveProcess == null)
                    this.postDataSaveProcess = new RelayCommand(PostDataSaveProcessExecuted);

                return this.postDataSaveProcess;
            }
        }


        public ICommand PostResetDefault
        {
            get
            {
                if (this.postResetDefault == null)
                    this.postResetDefault = new RelayCommand(PostResetDefaultExecuted);

                return this.postResetDefault;
            }
        }

        public ICommand PreResetDefault
        {
            get
            {
                if (this.preResetDefault == null)
                    this.preResetDefault = new RelayCommand(PreResetDefaultExecuted);

                return this.preResetDefault;
            }
        }


        public ICommand PreDataDelValidate
        {
            get
            {
                if (this.preDataDelValidation == null)
                    this.preDataDelValidation = new RelayCommand(PreDataDelValidationExecuted);

                return this.preDataDelValidation;
            }
        }

        public ICommand AddAdditionalReportParameters
        {
            get
            {
                if (this.addAdditionalReportParamters == null)
                    this.addAdditionalReportParamters = new RelayCommand(AddAddionalReportParametersExecuted);

                return this.addAdditionalReportParamters;
            }
        }

        #endregion




        protected virtual void SetDataSourcesAndProperties()
        {
        }


        /// <summary>
        /// Validate mandatory data before save
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PreDataValidateExecuted(object obj)
        {
        }

        protected virtual void PostDataValidateExecuted(object obj)
        {
        }

        /// <summary>
        ///  This can be used to update master specific data
        /// </summary>

        protected virtual void PostDataUpdateExecuted(object obj)
        {
        }


        /// <summary>
        ///  This can be used to save master specific data
        /// </summary>

        protected virtual void PostDataInsertExecuted(object obj)
        {
        }


        /// <summary>
        ///  This can be used to delete master specific data
        ///  before deleting the master record
        /// </summary>

        protected virtual void PreDataDeleteExecuted(object obj)
        {
        }

        /// <summary>
        ///  This can be used to delete master specific data
        ///  after deleting the master record
        /// </summary>

        protected virtual void PostDataDeleteExecuted(object obj)
        {
        }

        /// <summary>
        /// To display master specific data
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void RefreshExternalDataObjectsExecueted(object obj)
        {
        }

        protected virtual void WindowLoadExcecuted(object obj)
        {


        }

        protected virtual void PostDataSaveProcessExecuted(object obj)
        {
        }

        public virtual void ResolveDependancies()
        {
            IUnityContainer container = GlobalVariables.GlobalUnityContainer;

            if (container != null)
            {
                MasterReadService = container.Resolve<IReadService>();
                MasterWriteService = container.Resolve<IWriteService>();
                ColumnWithValue = container.Resolve<IColumnWithValue>();
                CommonValidations = container.Resolve<ICommonValidations>();
                MessageService = container.Resolve<IMessageService>();
            }

        }

        /// <summary>
        /// This method can be overriden in viewmodels to enable/disable
        /// master specific controls.
        /// </summary>
        protected virtual void EnableDisableSpecificControls()
        {
        }

        /// <summary>
        /// This can be used to do any updates before inserting a new record.
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PreDataInsertExecuted(object obj)
        {
        }
        /// <summary>
        /// This can be used to do any updates before updating an exisiting record.
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PreDataUpdateExecuted(object obj)
        {
        }

        /// <summary>
        /// To do any updates after setting the defaults
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PostResetDefaultExecuted(object obj)
        {
        }
        /// <summary>
        ///  To do any updates before setting to defaults
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PreResetDefaultExecuted(object obj)
        {
        }

        protected virtual void PreDataDelValidationExecuted(object obj)
        {
        }

        /// <summary>
        /// This can be used to add any additional parameters to the report
        /// </summary>
        protected virtual void AddAddionalReportParametersExecuted(object obj)
        {
        }

    }
}
